home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / packet / p_g8bpq / samall / samall.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-15  |  25.8 KB  |  927 lines

  1. /*
  2.  * samall.c
  3.  */
  4.  
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <dos.h>
  10. #include <ctype.h>
  11. #include <conio.h>
  12. #include <time.h>
  13.  
  14. #include "samapi.h"
  15.  
  16. #define TRUE 1
  17. #define FALSE 0
  18. #define TIMEOUT 180
  19.  
  20. /*
  21.  * functions in samlib.c; must be passed to compiler during link phase
  22.  */
  23.  
  24. int LocateSam(void);
  25. int CallSam(int cmd, void far *cmdbuf, void far *rspbuf);
  26.  
  27. /*
  28.  * decls for functions contained here
  29.  */
  30.  
  31. int samc(char *, char *, char *, char *,int, char);
  32. void transmit_data(datarec_t *);
  33. int  Check_BPQ(int);
  34. void Raise_RTS(int);
  35. void Lower_RTS(int);
  36. void Send_Break(int);
  37. int  Write_TNC(int, char *, unsigned int);
  38. void Return_To_Node(int);
  39. int  Connected(char *, int);
  40. int  Read_TNC(int, char *);
  41. void Set_TNC(int, int);
  42. void Reset_TNC(int);
  43. void cru(char *);
  44. void Delay(int);
  45. void DV_Nice(void);
  46. int Ready(void);
  47.  
  48. int port;
  49. int bycall = FALSE;
  50. int byname = FALSE;
  51. int oncmd = FALSE;
  52.  
  53.  
  54.  
  55.  
  56. int main(int argc, char *argv[])
  57. {
  58.  
  59. char *buffer;
  60. char *inbuff;
  61. char *call;
  62. char *usercall;
  63. char *lastname;
  64. char *firstname;
  65. char *middleinitial;
  66. char response, initial_response;
  67. time_t start_time;
  68. time_t current_time;
  69. time_t user_start_time;
  70. time_t user_stop_time;
  71. char tstr[80];
  72.  
  73. int appl_number;
  74. int  i, j, l, k, m, n;
  75. int timedout;
  76.  
  77. if (argc != 3)
  78. {
  79. fprintf(stderr, "Usage: SAMALL port appl_nmbr \n");
  80. exit(1);
  81. }
  82.  
  83. /* The INT 14H port number is 1 below the commonly used port*/
  84. /* numbers. eg COM1: = 0, COM2: = 1 etc.*/
  85.  
  86. port = atoi(argv[1]) - 1;
  87.  
  88. appl_number = atoi(argv[2]);
  89.  
  90. if (!Check_BPQ(port))
  91. exit(1);
  92.  
  93. /*
  94.  * make sure the resident code (SAMAPI.EXE)
  95.  * has been installed
  96.  */
  97.  
  98. if (LocateSam())
  99. {
  100.         printf("*** SAMAPI not loaded\n");
  101.         exit(2);
  102. }
  103.  
  104. Set_TNC(appl_number, port);
  105.  
  106. usercall = calloc(12, sizeof(char));
  107.  
  108. time(¤t_time);
  109. printf("version 2.50 Server started: %s", ctime(¤t_time));
  110.  
  111. while (!kbhit())
  112. {
  113. if (Connected(usercall, port))
  114. {
  115.      inbuff = calloc(2048, sizeof(char));
  116.      buffer = calloc(2048, sizeof(char));
  117.      call = calloc(10, sizeof(char));
  118.      lastname = calloc(512, sizeof(char));
  119.      firstname = calloc(512, sizeof(char));
  120.      middleinitial = calloc(10, sizeof(char));
  121.  
  122.      n=1; j=0;
  123.      j = Read_TNC(port, inbuff);
  124.      for( i = 5; i <= j; i++)
  125.         if(isalnum(inbuff[i]))
  126.              {
  127.                 call[i-5] = inbuff[i];
  128.                 n += 1;
  129.              }
  130.      call[n] = '\0';
  131.  
  132.      if( (n < 5) || (n > 7) )
  133.      {
  134.             bycall = FALSE;
  135.             byname = FALSE;
  136.             oncmd = FALSE;
  137.  
  138.             Send_Break(port);
  139.  
  140.             strcpy(buffer, "CONV\r");
  141.             Write_TNC(port, buffer, strlen(buffer));
  142.  
  143.             time(&user_start_time);
  144.             strcpy(tstr, ctime(&user_start_time));
  145.             tstr[(strlen(tstr)-1)] = '\0';
  146.  
  147.             printf("%s on at %s", usercall, tstr);
  148.  
  149.             strcpy(buffer, "Welcome to the SAM database Server.");
  150.             strcat(buffer, "\r");
  151.             strcat(buffer, "Developed by KK4L.  15 Mar. 1992");
  152.             strcat(buffer, "\r");
  153.             strcat(buffer, "Inactivity timeout is set to 3 minutes.");
  154.             strcat(buffer, "\r");
  155.             strcat(buffer, "To avoid this menu, send the command:  ");
  156.             strcat(buffer, "\r");
  157.             strcat(buffer, "       FIND xxxxx ");
  158.             strcat(buffer, "\r");
  159.             strcat(buffer, "where xxxxx is the callsign of interest.");
  160.             strcat(buffer, "\r");
  161.             strcat(buffer, "Follow the prompts.  Press enter by itself to enter a blank.");
  162.             strcat(buffer, "\r");
  163.             strcat(buffer, " enter:  N)ame to find by name");
  164.             strcat(buffer, " \r");
  165.             strcat(buffer, " enter:  C)all to find by callsign or");
  166.             strcat(buffer, "\r");
  167.             strcat(buffer, " enter:  Q)uit to return to the node.");
  168.             strcat(buffer, "\r");
  169.             strcat(buffer, "(N, C, Q) > \r");
  170.             Write_TNC(port, buffer, strlen(buffer));
  171.             Read_TNC(port, buffer);
  172.  
  173.             timedout = FALSE;
  174.  
  175.             time(&start_time);
  176.             do
  177.             {
  178.               j = Read_TNC(port, inbuff);
  179.               initial_response = toupper(inbuff[0]);
  180.               time(¤t_time);
  181.               if((current_time - start_time) >= TIMEOUT) timedout = TRUE;
  182.               if(initial_response == 'Q') timedout = TRUE;
  183.             } while((initial_response != 'Q') && (timedout == FALSE)
  184.                  && (initial_response != 'N') && (initial_response != 'C'));
  185.  
  186.             if((timedout == FALSE) && (initial_response != 'Q'));
  187.               {
  188.                  if(initial_response == 'N')
  189.                    {
  190.                            byname = TRUE;
  191.                            bycall = FALSE;
  192.  
  193.                            strcpy(buffer, "Last  Name ?");
  194.                            strcat(buffer, "\r");
  195.                            Write_TNC(port, buffer, strlen(buffer));
  196.  
  197.                            time(&start_time);
  198.                            do
  199.                            {
  200.                              j = Read_TNC(port, inbuff);
  201.                              time(¤t_time);
  202.                              if((current_time - start_time) >= TIMEOUT) timedout = TRUE;
  203.                            } while((timedout == FALSE) && (inbuff[0] == '\0'));
  204.  
  205.                           if(timedout == FALSE)
  206.                             {
  207.                                k = 0;
  208.                                for( i = 0; i <= j; i++)
  209.                                  if(isalpha(inbuff[i]))
  210.                                    {
  211.                                       lastname[k] = inbuff[i];
  212.                                       k += 1;
  213.                                    }
  214.                                lastname[k] = '\0';
  215.  
  216.                                strcpy(buffer, "First Name ?");
  217.                                strcat(buffer, "\r");
  218.                                Write_TNC(port, buffer, strlen(buffer));
  219.  
  220.                                time(&start_time);
  221.                                do
  222.                                {
  223.                                  j = Read_TNC(port, inbuff);
  224.                                  time(¤t_time);
  225.                                  if((current_time - start_time) >= TIMEOUT) timedout = TRUE;
  226.                                } while((timedout == FALSE) && (inbuff[0] == '\0'));
  227.  
  228.                                if(timedout == FALSE)
  229.                                  {
  230.                                     k = 0;
  231.                                     for( i = 0; i <= j; i++)
  232.                                       if(isalpha(inbuff[i]))
  233.                                         {
  234.                                            firstname[k] = inbuff[i];
  235.                                            k += 1;
  236.                                         }
  237.                                     firstname[k] = '\0';
  238.  
  239.                                     strcpy(buffer, "Middle Initial ?");
  240.                                     strcat(buffer, "\r");
  241.                                     Write_TNC(port, buffer, strlen(buffer));
  242.  
  243.                                     time(&start_time);
  244.                                     do
  245.                                     {
  246.                                       j = Read_TNC(port, inbuff);
  247.                                       time(¤t_time);
  248.                                       if((current_time - start_time) >= TIMEOUT) timedout = TRUE;
  249.                                     } while((timedout == FALSE) && (inbuff[0] == '\0'));
  250.  
  251.                                     if(timedout == FALSE)
  252.                                       {
  253.                                          if(isalpha(inbuff[0])) middleinitial[0] = inbuff[0];
  254.                                            else middleinitial[0] = '\0';
  255.                                          middleinitial[1] = '\0';
  256.                                       }
  257.                                  }
  258.                             }
  259.  
  260.                            strcpy(buffer, "Looking for name: ");
  261.                            Write_TNC(port, buffer, strlen(buffer));
  262.                            strcpy(buffer, lastname);
  263.                            if(strlen(lastname) > 0) strcat(buffer, ", ");
  264.                               else strcat(buffer, " ");
  265.                            strcat(buffer, firstname);
  266.                            strcat(buffer, " ");
  267.                            strcat(buffer, middleinitial);
  268.                            if(strlen(middleinitial) > 0) strcat(buffer, ".");
  269.                            strcat(buffer, "\r");
  270.                            Write_TNC(port, buffer, strlen(buffer));
  271.                            samc('\0', lastname, firstname, middleinitial, 6, 'N');
  272.  
  273.                    }
  274.  
  275.                  if(initial_response == 'C')
  276.                    {
  277.                        byname = FALSE;
  278.                        bycall = TRUE;
  279.  
  280.                        strcpy(buffer, "Callsign ?");
  281.                        strcat(buffer, "\r");
  282.                        Write_TNC(port, buffer, strlen(buffer));
  283.  
  284.                        time(&start_time);
  285.                        do
  286.                        {
  287.                          j = Read_TNC(port, inbuff);
  288.                          time(¤t_time);
  289.                          if((current_time - start_time) >= TIMEOUT) timedout = TRUE;
  290.                        } while((timedout == FALSE) && (inbuff[0] == '\0'));
  291.  
  292.  
  293.                       if(timedout == FALSE)
  294.                         {
  295.                            i = 0;
  296.                            for(l = 0; l <= j; l++)
  297.                              {
  298.                                 if(isalnum(inbuff[l]))
  299.                                   {
  300.                                      call[i++] = inbuff[l];
  301.                                   }
  302.                               }
  303.                            call[i] = '\0';
  304.                         }
  305.  
  306.                        strcpy(buffer, "Looking for callsign: ");
  307.                        Write_TNC(port, buffer, strlen(buffer));
  308.                        strcpy(buffer, call);
  309.                        strcat(buffer, "\r");
  310.                        Write_TNC(port, buffer, strlen(buffer));
  311.                        samc(call,'\0','\0','\0', 4, 'N');
  312.  
  313.                    }
  314.  
  315.                 time(&start_time);
  316.                 do
  317.                 {
  318.                   j = Read_TNC(port, inbuff);
  319.                   response = toupper(inbuff[0]);
  320.                   if(response == 'N')
  321.                     {
  322.                         time(&start_time);
  323.                         if(bycall) samc("","" ,"" ,"" , 5, 'N');
  324.                         if(byname) samc("","" ,"" ,"" , 7, 'N');
  325.                     }
  326.                   if(response == 'P')
  327.                     {
  328.                         time(&start_time);
  329.                         if(bycall) samc("","" ,"" ,"" , 5, 'P');
  330.                         if(byname) samc("","" ,"" ,"" , 7, 'P');
  331.                     }
  332.                   time(¤t_time);
  333.                   if((current_time - start_time) >= TIMEOUT) timedout = TRUE;
  334.                 } while((response != 'Q') &&
  335.                          (timedout == FALSE));
  336.               }
  337.      }
  338.      else
  339.          {
  340.             byname = FALSE;
  341.             bycall = FALSE;
  342.             oncmd = TRUE;
  343.  
  344.             Send_Break(port);
  345.  
  346.             strcpy(buffer, "CONV\r");
  347.             Write_TNC(port, buffer, strlen(buffer));
  348.  
  349.             time(&user_start_time);
  350.             strcpy(tstr, ctime(&user_start_time));
  351.             tstr[(strlen(tstr)-1)] = '\0';
  352.  
  353.             printf("%s on at %s using Quicklook.", usercall, tstr);
  354.  
  355.             samc(call,'\0','\0','\0', 4, 'N');
  356.           }
  357.  
  358.      Send_Break(port);
  359.      Read_TNC(port, inbuff);
  360.      Delay(3);
  361.      Return_To_Node(port);
  362.      time(&user_stop_time);
  363.      if(!oncmd) printf(" returned to node after %d seconds.\n", (user_stop_time - user_start_time));
  364.         else printf(" Returned to node.\n");
  365.  
  366.      free(inbuff);
  367.      free(buffer);
  368.      free(call);
  369.      free(lastname);
  370.      free(firstname);
  371.      free(middleinitial);
  372.  
  373.  
  374.  
  375. }
  376. else DV_Nice();
  377. }
  378.  
  379. Reset_TNC(port);
  380.  
  381. free(usercall);
  382.  
  383. return(0);
  384.  
  385. }
  386.  
  387. /***********************************************************************/
  388. /*  DV_Nice - gives back ticks to DesqView                             */
  389. /***********************************************************************/
  390.  
  391. void DV_Nice(void)
  392. {
  393. union REGS regs;
  394.  
  395.  regs.x.ax = 0x1000;
  396.  int86(0x15, ®s, ®s);
  397.  
  398. }
  399.  
  400. /************************************************************************/
  401. /* This checks for the G8BPQ Node signiature of X'AA55' in BOTH AX and*/
  402. /* BX. COMBIOS and related programs only return it in AX. The version*/
  403. /* number is also retrieved, this could be checked if using a newly*/
  404. /* implemented feature of the code.*/
  405. /************************************************************************/
  406.  
  407. int Check_BPQ(int port)
  408. {
  409. union REGS regs;
  410.  
  411. regs.x.dx = port;
  412. regs.h.ah = 4;
  413.  
  414. int86(0x14, ®s, ®s);
  415.  
  416. if (regs.x.ax != 0xAA55 || regs.x.bx != 0xAA55)
  417. {
  418. fprintf(stderr, "SAMALL: G8BPQ node support not loaded\n");
  419. return(FALSE);
  420. }
  421.  
  422. regs.x.dx = port;
  423. regs.h.ah = 0x1F;
  424. regs.h.al = 0;
  425.  
  426. int86(0x14, ®s, ®s);
  427.  
  428. return(TRUE);
  429. }
  430.  
  431. /********************************************
  432.  *************  Raise_RTS  ******************
  433.  ********************************************/
  434. void Raise_RTS(int port)
  435. {
  436. union REGS regs;
  437.  
  438. regs.x.dx = port;
  439. regs.h.ah = 6;
  440.  
  441. int86(0x14, ®s, ®s);
  442. }
  443.  
  444. /********************************************
  445.  *************  Lower_RTS  ******************
  446.  ********************************************/
  447. void Lower_RTS(int port)
  448. {
  449. union REGS regs;
  450. regs.x.dx = port;
  451. regs.h.ah = 5;
  452.  
  453. int86(0x14, ®s, ®s);
  454. }
  455.  
  456. /************************************************************************/
  457. /* Sending a break to the node software is the sure-fire way of getting*/
  458. /* back to command mode from converse and transparant mode.*/
  459. /************************************************************************/
  460.  
  461. void Send_Break(int port)
  462. {
  463. union REGS regs;
  464.  
  465. regs.x.dx = port;
  466. regs.h.ah = 7;
  467.  
  468. int86(0x14, ®s, ®s);
  469. }
  470.  
  471. /************************************************************************/
  472. /* This function takes the same sort of arguments as the C library*/
  473. /* function write(). It is a non blocking function that returns when*/
  474. /* either all of the data has been sent to the node, or when the node*/
  475. /* cannot accept any more data.*/
  476. /************************************************************************/
  477.  
  478. int Write_TNC(int port, char *buf, unsigned int count)
  479. {
  480. union REGS regs;
  481. int attempts = 0;
  482. int i;
  483.  
  484. for (i = 0; i < count; i++)
  485. {
  486. regs.x.dx = port;
  487. regs.h.ah = 3;
  488.  
  489. do
  490. {
  491. attempts++;
  492.  
  493. int86(0x14, ®s, ®s);
  494. }
  495. while (!(regs.h.ah & 0x20) && (attempts < 32));
  496.  
  497. if (attempts == 32)
  498. return(i);
  499.  
  500. attempts = 0;
  501.  
  502. regs.x.dx = port;
  503. regs.h.ah = 1;
  504. regs.h.al = buf[i];
  505.  
  506. int86(0x14, ®s, ®s);
  507. }
  508. return(i);
  509. }
  510.  
  511. /************************************************************************/
  512. /* This is the gracefull way of getting rid of users, until recently the*/
  513. /* only available option was to disconnect them from the node, this puts*/
  514. /* them back to the node software.*/
  515. /************************************************************************/
  516.  
  517. void Return_To_Node(int port)
  518. {
  519. union REGS regs;
  520.  
  521. regs.x.dx = port;
  522. regs.h.ah = 0x1F;
  523. regs.h.al = 0x10;
  524.  
  525. int86(0x14, ®s, ®s);
  526. }
  527.  
  528. /************************************************************************/
  529. /* This function serves two purposes, it indicates whether the*/
  530. /* application is connected to a user, and if so, what their callsign*/
  531. /* is. At present it does not return the users ssid, but it is available*/
  532. /* if needed. The code gets the users callsign from the INT 14H and not*/
  533. /* from parsing the "*** CONNECTED to ..." line. This piece of the code*/
  534. /* makes use of a far pointer to the callsign within the Node software.*/
  535. /* It then has to be converted to ASCII from AX25 format, which is*/
  536. /* essentially shifting the characters right by one bit.*/
  537. /************************************************************************/
  538.  
  539. int Connected(char *buff, int port)
  540. {
  541. union REGS regs;
  542. struct SREGS segregs;
  543. unsigned char far *calls;
  544. int i;
  545.  
  546. regs.x.dx = port;
  547. regs.h.ah = 0x1F;
  548. regs.h.al = 1;
  549.  
  550. int86x(0x14, ®s, ®s, &segregs);
  551.  
  552. if (regs.x.si == 0)
  553. return(FALSE);
  554.  
  555. calls = MK_FP(segregs.es,regs.x.si);
  556.  
  557. for (i = 0; (calls[i] >> 1) != ' ' && i < 6; i++)
  558. buff[i] = calls[i] >> 1;
  559.  
  560. buff[i] = '\0';
  561.  
  562. return(TRUE);
  563. }
  564.  
  565.  
  566. /************************************************************************/
  567. /* This routine is a non-blocking read of the port input stream.*/
  568. /************************************************************************/
  569.  
  570. int Read_TNC(int port, char *buffer)
  571. {
  572. union REGS regs;
  573. int i;
  574.  
  575. regs.x.dx = port;
  576. regs.h.ah = 3;
  577.  
  578. int86(0x14, ®s, ®s);
  579.  
  580. i = 0;
  581.  
  582. while (regs.h.ah & 0x01)
  583. {
  584. regs.x.dx = port;
  585. regs.h.ah = 2;
  586.  
  587. int86(0x14, ®s, ®s);
  588.  
  589. buffer[i++] = regs.h.al;
  590.  
  591. regs.x.dx = port;
  592. regs.h.ah = 3;
  593.  
  594. int86(0x14, ®s, ®s);
  595. }
  596.  
  597. buffer[i] = '\0';
  598.  
  599. return(i);
  600. }
  601.  
  602. /********************************************
  603.  *************  Set_TNC  ********************
  604.  ********************************************/
  605. void Set_TNC(int appl_number, int port)
  606. {
  607. char *command;
  608. char *buff;
  609.  
  610. Raise_RTS(port);
  611.  
  612. Send_Break(port);
  613.  
  614. buff = calloc(1024, sizeof(char));
  615. command = calloc(80, sizeof(char));
  616.  
  617. command = "ECHO OFF\r";
  618. Write_TNC(port, command, strlen(command));
  619. Read_TNC(port, buff);
  620.  
  621. sprintf(buff, "APPL $%02X\r", appl_number);
  622. Write_TNC(port, buff, strlen(buff));
  623. Read_TNC(port, buff);
  624.  
  625. command = "MONITOR OFF\r";
  626. Write_TNC(port, command, strlen(command));
  627. Read_TNC(port, buff);
  628.  
  629. command = "CONOK ON\r";
  630. Write_TNC(port, command, strlen(command));
  631. Read_TNC(port, buff);
  632.  
  633. free(buff);
  634. free(command);
  635.  
  636. }
  637.  
  638.  
  639. /********************************************
  640.  *************  Reset_TNC  ******************
  641.  ********************************************/
  642. void Reset_TNC(int port)
  643. {
  644. char *command;
  645. char *buff;
  646.  
  647. Send_Break(port);
  648.  
  649. buff = calloc(1024, sizeof(char));
  650. command = calloc(80, sizeof(char));
  651.  
  652. command = "APPL $00\r";
  653. Write_TNC(port, command, strlen(command));
  654. Read_TNC(port, buff);
  655.  
  656. command = "CONOK OFF\r";
  657. Write_TNC(port, command, strlen(command));
  658. Read_TNC(port, buff);
  659.  
  660. Lower_RTS(port);
  661.  
  662. free(buff);
  663. free(command);
  664.  
  665. }
  666.  
  667. /************************************************************************/
  668. /* This function takes its name from a UNIX utility at Nottingham Uni*/
  669. /* called Carriage Return Utility. It converts between the carriage*/
  670. /* returns standards found on packet radio to the standards used in DOS*/
  671. /************************************************************************/
  672.  
  673. void cru(char *string)
  674. {
  675. int i;
  676.  
  677. for (i = 0; string[i] != '\0'; i++)
  678. {
  679. switch (string[i])
  680. {
  681. case '\r':
  682. string[i] = '\n';
  683. break;
  684. case '\n':
  685. string[i] = '\r';
  686. break;
  687. }
  688. }
  689. }
  690.  
  691.  
  692. /************************************************************************/
  693. /* Delay for n seconds. In a "real" piece of software, it would be wise*/
  694. /* to give time slices to DESQview at the point. The same can also be*/
  695. /* said of the loop in main() where it is waiting for a user.*/
  696. /************************************************************************/
  697.  
  698. void Delay(int delay)
  699. {
  700. time_t start_time;
  701. time_t current_time;
  702.  
  703. time(&start_time);
  704.  
  705. do
  706. {
  707. DV_Nice();
  708. time(¤t_time);
  709. }
  710. while ((current_time - start_time) < delay);
  711. }
  712.  
  713.  
  714. /**********************************************************************/
  715. /*  SAM supplied lookup routines for callsign lookup without scroll ***/
  716. /**********************************************************************/
  717.  
  718. int samc(char *callin, char *lastnamein, char *firstnamein, char *middleinitialin, int func, char updwn)
  719. {
  720. char *buffer;
  721. cmdfindname_t sam_name_in;
  722. cmdgetrecs_t sam_next;
  723. cmdfindcall_t sam_in;
  724. rspdatarec_t sam_out;
  725. int err;
  726.  
  727.         /*
  728.          * No un-assigned pointers here!
  729.          */
  730.  
  731.         buffer = calloc(1024, sizeof(char));
  732.  
  733.         /*
  734.          * build command block and call SAMAPI, function SamFindCall
  735.          */
  736.         if(func == 4)
  737.         {
  738.           sam_in.packflags = 0;   /* 0 to unpack all data record fields */
  739.           strncpy(sam_in.call, callin, 6);
  740.           sam_in.call[6] = 0;
  741.           err = CallSam(SamFindCall, &sam_in, &sam_out);
  742.           if (err == SerrNotFound)
  743.           {
  744.                   if(!oncmd) strcpy(buffer, "Not found but the closest call is:");
  745.                   else {
  746.                            strncpy(buffer, callin, strlen(callin));
  747.                            strcat(buffer, " not found ...");
  748.                        }
  749.  
  750.                   strcat(buffer, "\r");
  751.                   strcat(buffer, "\r");
  752.                   Write_TNC(port, buffer, strlen(buffer));
  753.          }
  754.           /*
  755.           * check for unusual error
  756.           * something other that plain ole not found
  757.           */
  758.  
  759.           if (err != 0 && err != SerrNotFound)
  760.           {
  761.  
  762.                   strcpy(buffer, "*** SAMAPI error ");
  763.                   strcat(buffer, "\r");
  764.                   strcat(buffer, "\r");
  765.                   Write_TNC(port, buffer, strlen(buffer));
  766.  
  767.                   return(2);
  768.           }
  769.         }
  770.  
  771.         if(func == 5)
  772.         {
  773.           sam_next.packflags = 0;   /* 0 to unpack all data record fields */
  774.           if(updwn == 'N') sam_next.index = sam_out.d.Cindex + 1;
  775.           if(updwn == 'P') sam_next.index = sam_out.d.Cindex - 1;
  776.           err = CallSam(SamGetRecordByCall, &sam_next, &sam_out);
  777.            /*
  778.            * check for unusual error
  779.            * something other that plain ole not found
  780.            */
  781.  
  782.            if (err != 0 && err != SerrNotFound)
  783.             {
  784.  
  785.                     strcpy(buffer, "*** SAMAPI error ");
  786.                     strcat(buffer, "\r");
  787.                     strcat(buffer, "\r");
  788.                     Write_TNC(port, buffer, strlen(buffer));
  789.  
  790.                     return(2);
  791.             }
  792.         }
  793.         /*
  794.          * build command block and call SAMAPI, function SamFindName
  795.          */
  796.         if(func == 6)
  797.         {
  798.           sam_name_in.packflags = 0;   /* 0 to unpack all data record fields */
  799.           strncpy(sam_name_in.lastname, lastnamein, 20);
  800.           strncpy(sam_name_in.firstname, firstnamein, 10);
  801.           strncpy(sam_name_in.midinitial, middleinitialin, 1);
  802.           err = CallSam(SamFindName, &sam_name_in, &sam_out);
  803.           if (err == SerrNotFound)
  804.           {
  805.                   strcpy(buffer, "Not found but the closest entry is:");
  806.                   strcat(buffer, "\r");
  807.                   strcat(buffer, "\r");
  808.                   Write_TNC(port, buffer, strlen(buffer));
  809.           }
  810.            /*
  811.            * check for unusual error
  812.            * something other that plain ole not found
  813.            */
  814.  
  815.            if (err != 0 && err != SerrNotFound)
  816.             {
  817.  
  818.                     strcpy(buffer, "*** SAMAPI error ");
  819.  
  820.                     strcat(buffer, "\r");
  821.                     strcat(buffer, "\r");
  822.                     Write_TNC(port, buffer, strlen(buffer));
  823.                     return(2);
  824.             }
  825.         }
  826.  
  827.         if(func == 7)
  828.         {
  829.           sam_next.packflags = 0;   /* 0 to unpack all data record fields */
  830.           if(updwn == 'N') sam_next.index = sam_out.d.Nindex + 1;
  831.           if(updwn == 'P') sam_next.index = sam_out.d.Nindex - 1;
  832.           err = CallSam(SamGetRecordByName, &sam_next, &sam_out);
  833.            /*
  834.            * check for unusual error
  835.            * something other that plain ole not found
  836.            */
  837.  
  838.            if (err != 0 && err != SerrNotFound)
  839.             {
  840.  
  841.                     strcpy(buffer, "*** SAMAPI error ");
  842.  
  843.                     strcat(buffer, "\r");
  844.                     strcat(buffer, "\r");
  845.                     Write_TNC(port, buffer, strlen(buffer));
  846.  
  847.                     return(2);
  848.             }
  849.         }
  850.  
  851.  
  852.         /*
  853.          * got a match, display the call data
  854.          */
  855.  
  856.         if(!oncmd)
  857.         {
  858.            transmit_data(&sam_out.d);
  859.            strcpy(buffer, "enter:   N)ext,  P)revious  or  Q)uit");
  860.            strcat(buffer, "\r");
  861.            strcat(buffer, "\r");
  862.            strcat(buffer, "(N, P, Q) >");
  863.            strcat(buffer, "\r");
  864.            Write_TNC(port, buffer, strlen(buffer));
  865.         }
  866.         else
  867.            if(err != SerrNotFound) transmit_data(&sam_out.d);
  868.  
  869.         /*
  870.          * exit with 0 for success
  871.          */
  872.         free(buffer);
  873.         return 0;
  874. }
  875.  
  876. /*******************
  877.  * transmit_data
  878.  *******************
  879.  *
  880.  * transmits data out the port formatted:
  881.  *  first [m ]last  callsign
  882.  *  address
  883.  *  city, st  zip
  884.  *  class       year born
  885.  *
  886.  * input is pointer to data record
  887.  *
  888.  * returns nothing
  889.  */
  890.  
  891. void transmit_data(datarec_t *d)
  892. {
  893. char *buff;
  894.  
  895.         buff = calloc(1024, sizeof(char));
  896.  
  897.         strcpy(buff, d->FirstName);
  898.         strcat(buff, " ");
  899.         if (d->MidInitial[0] != ' ')
  900.             {
  901.                 strcat(buff, d->MidInitial);
  902.                 strcat(buff, " ");
  903.             }
  904.         strcat(buff, d->LastName);
  905.         strcat(buff, "   ---  ");
  906.         strcat(buff, d->Call + (d->Call[0] == ' '));
  907.         strcat(buff, "\r");
  908.         strcat(buff, d->Address);
  909.         strcat(buff,"\r");
  910.         Write_TNC(port, buff, strlen(buff));
  911.         strcpy(buff, d->City);
  912.         strcat(buff, ",  ");
  913.         strcat(buff, d->State);
  914.         strcat(buff, "   ");
  915.         strcat(buff, d->Zip);
  916.         strcat(buff, "\r");
  917.         strcat(buff, "License Class: ");
  918.         strcat(buff, d->Class);
  919.         strcat(buff, "    Year Born: 19");
  920.         strcat(buff, d->Dob);
  921.         strcat(buff, "\r");
  922.         strcat(buff, "\r");
  923.         Write_TNC(port, buff, strlen(buff));
  924.         free(buff);
  925. }
  926.  
  927.